
import { useState, useEffect, useCallback } from "react";
import { Dropdown, Input, Layout, Menu, Modal, message } from "antd";
import { MenuOutlined, SearchOutlined, LoadingOutlined } from '@ant-design/icons'

import GroupSearch from "../groupSearch";
import GroupListItem from '../groupListItem'
import GroupCreate from "../groupCreate";

import {
    room_wrapper_left,
    room_left_header,
    room_left_header_input,
    room_left_list,
    room_item,
} from '../../pages/room/index.module.css'
import {
    search_result_list,
    group_list,
    group_list_setting,
    group_list_setting_content,
    group_list_menu,
    group_list_tip,
    group_list_tip_txt_btn,
    group_modal,
} from './index.module.css'
import { RTrim } from '../../assets/js/tools'
import { connect } from "react-redux";

import { getGroupUserJoin, getLastSysteMessage } from '../../assets/js/api'
import {
    joinRoom,
    offGroupQuit,
    offJoinGroup,
    offSocketRoomMessage,
    onGroupQuit,
    onJoinGroup,
    onSocketRoomMessage,
} from '../../socketEvent'
import { publish, subscribe, unsubscribe } from 'pubsub-js';
import { getMessage, systemMessage } from '../../event-type';
import { changeCurrentRoom, changeCurrentRoomInfo } from "../../store/actions";

const {Header,Sider} = Layout;


function GroupList(props) {

    const { user, currentRoom, changeCurrentRoom, changeCurrentRoomInfo } = props;

    const [searchResult, setSearchResult] = useState([]);
    const [searchKeyword, setSearchKeyword] = useState('');
    const [visibleMenu, setVisibleMenu] = useState(false);
    const [modalVisible, setModalVisible] = useState(false);
    const [searchGroupModalVisible, setSearchGroupModalVisible] = useState(false);  // 显示搜索群组框
    const [createGroupModalVisible, setCreateGroupModalVisible] = useState(false);  // 显示创建群组框

    
    const [systemMessageContent, setSystemMessageContent] = useState({});
    const [groupsInfo, setGroupsInfo] = useState([]);
    const [groupsInfoErr, setGroupsInfoErr] = useState(true);
    const [loading, setLoading] = useState(false);

    const newMessage = useCallback((val, data) => {
        // 有最新消息时,显示最新消息
        setGroupsInfo(item => {
            const result = [...item];
            const newGroupMessageIndex = result.findIndex(v => v.group_id === val.group_id);
            const cutGroupMessage = result.splice(newGroupMessageIndex, 1)[0];
            cutGroupMessage.no_check += 1;
            cutGroupMessage.send_time = data.send_time;
            cutGroupMessage.message_id = data.message_id;
            cutGroupMessage.message_content = data.message_content;
            cutGroupMessage.user_id = data.user_id;
            cutGroupMessage.name = data.name;
            cutGroupMessage.avator = data.avator;
            result.splice(newGroupMessageIndex, 0, cutGroupMessage);
            return result;
        });
        if (val.group_id === currentRoom) {
            publish(getMessage, data);
        }
    }, [currentRoom]);
    const getGroupsInfo = useCallback(() => {
        // 请求用户所加入的群组信息和群组的最后一条消息
        return new Promise((resolve, reject) => {
            getGroupUserJoin({user_id:user.id})
            .then(res => {
                const { code, message: content, data } = res.data;
                if (code !== 1) {
                    message.error({content});
                    setGroupsInfoErr(true);
                    reject();
                    return;
                }
                
                setGroupsInfoErr(false);
                setGroupsInfo(data);
                // 连接socket
                joinRoom(data.map(val => val.group_id));
                resolve();
            })
            .catch(err => {
                reject(err);
                console.error(err);
            });
        });
    }, [user.id]);
    const getSystemMessage = useCallback(() => {
        // 获取系统消息最后一条
        return new Promise((resolve, reject) => {
            getLastSysteMessage({user_id: user.id})
            .then(res => {
                const {code, message:message_content, send_time, no_check} = res.data;
                if (code !== 1) {
                    reject(message_content);
                    return;
                }
                
                setSystemMessageContent({
                    group_id: 0, 
                    group_avator: 'system_message',
                    name: '', 
                    message_content,
                    send_time,
                    no_check
                });
                resolve();
            })
            .catch(err => {
                reject(err);
                console.error(err);
            });
        });
    }, [user.id]);
    const getGroupList = useCallback(() => {
        // 获取列表需要的信息
        if (loading || user.id === -1) return;
        setLoading(true);

        Promise.all([getGroupsInfo(), getSystemMessage()])
        .finally(() => { 
            setLoading(false);
        });
    }, [loading, user.id, getGroupsInfo, getSystemMessage]);
    
    
    useEffect(() => {
        // 不将getGroupList放入依赖项,因为getGroupList依赖loading,当loading改变会时getGroupList改变,时getGroupList再次调用,造成循环
        getGroupList();
    }, []);
    useEffect(() => {

        onJoinGroup(data => {
            console.log(`你加入了群组${data.group_name}`)
            setGroupsInfo(val => [...val, data]);
        });
        onGroupQuit(({group_id}) => {
            if (+currentRoom === +group_id) {
                changeCurrentRoom(-1);
                changeCurrentRoomInfo();
            }
            setGroupsInfo(val => {
               const result = [...val];
               result.splice(
                   result.findIndex(item => item.group_id === +group_id), 
                   1
                );
               return result;
            });
        });

        // 系统消息
        const systemMessageToken = subscribe(systemMessage, (event, data) => {
            setSystemMessageContent(val => ({
                group_id: 0, 
                message_content: data.message_content,
                group_avator: 'system_message',
                name: '', 
                send_time: data.send_time,
                no_check: val.no_check+1
            }));
        });
        return () => {
            offJoinGroup();
            offGroupQuit();
            
            unsubscribe(systemMessageToken);
        }
    }, [currentRoom,changeCurrentRoom]);
    useEffect(() => {
        // 获取到用户加入群组后对群组消息进行监听,有新消息即使显示
        groupsInfo.forEach(val => {
            onSocketRoomMessage(val.group_id, res => {
                const {type, data} = res;
                if (type === 'message') {
                    newMessage(val, data);
                } else if (type === 'change') {
                    changeGroupInfo(val, data);
                }
                
            });
        });
        return () => {
            groupsInfo.forEach(val => offSocketRoomMessage(val.group_id));
        }
    }, [newMessage, groupsInfo]);


    
    function changeGroupInfo(val, data) {
        // 当群组头像或名称改变时,将groupList的显示改变
        setGroupsInfo(preData => {
            const result = [...preData];
            const newGroupMessageIndex = result.findIndex(v => v.group_id === val.group_id);
            const cutGroupMessage = result.splice(newGroupMessageIndex, 1)[0];
            
            cutGroupMessage.group_name = data.group_name ?? cutGroupMessage.group_name;
            cutGroupMessage.group_avator = data.group_avator ?? cutGroupMessage.group_avator;
            result.splice(newGroupMessageIndex, 0, cutGroupMessage);
            return result;
        });
    }
    
    function screenGroup(e) {
        // 搜索群组
        let value = RTrim(e.target.value);
        if (value === '') {
            setSearchKeyword(value);
            setSearchResult([]);
            return;
        }
        setSearchKeyword(value);
        setSearchResult(groupsInfo.filter(item => item.group_name.includes(value)));
    }
    function showSearchResultMenu() {
        // 用于创建搜索结果列表
        return (
            <Menu 
                style={{width: '280px'}}
                selectable={false}
            >
                {
                    sortGroupList(searchResult).map(info => {
                        return (
                            <Menu.Item 
                                className={search_result_list} 
                                style={{height: '80px'}} 
                                key={info.group_id}
                            >
                                <GroupListItem 
                                    className={room_item} 
                                    info={info} 
                                    visibleTip={false} 
                                    hoverBackColor={false}
                                    highLight={searchKeyword}
                                    clearCheck={() => info.no_check = 0} 
                                />
                            </Menu.Item>
                        )
                    })
                }
            </Menu>
        )
    }
    function sortGroupList(sortArr) {
        // 对群组排序,最近的发送时间在最上面
        return sortArr.sort((a,b) => new Date(b.send_time).getTime() - new Date(a.send_time).getTime());
    }
    function closeAllModal() {
        // 关闭所有的弹出框
        setSearchGroupModalVisible(false);
        setModalVisible(false);
    }
    function showSearchGroup() {
        // 打开群组搜索
        setSearchGroupModalVisible(true);
        setModalVisible(true);
    }
    function showCreateGroup() {
        // 打开创建群组
        setCreateGroupModalVisible(true)
        setModalVisible(true);
    }


    return (
        <>
            <Layout className={room_wrapper_left}>
                <Header className={room_left_header}>
                    <Dropdown
                        trigger={['click']}
                        overlay={
                            visibleMenu ?
                                searchResult.length > 0 ?
                                    showSearchResultMenu() :
                                        searchKeyword !== '' ?
                                        <Menu 
                                            style={{width: '280px', padding: '10px 5px'}}
                                        >
                                            搜索无结果。。。
                                        </Menu> : 
                                        ''
                            :
                            ''
                        }
                    >
                        <Input 
                            className={room_left_header_input} 
                            bordered={false} 
                            prefix={<SearchOutlined />} 
                            placeholder="搜索" 
                            onChange={screenGroup}    
                            onFocus={()=>setVisibleMenu(true)}
                        />
                    </Dropdown>
                </Header>
                <Layout>
                    <Sider className={room_left_list} width={280}>
                        <div className={group_list}>
                            {
                                loading ? 
                                    <div className={group_list_tip}><LoadingOutlined style={{fontSize: '40px'}} /></div> :
                                    groupsInfoErr ? 
                                        <div className={group_list_tip}>
                                            网络错误, 您可以点击
                                            <span className={group_list_tip_txt_btn} onClick={getGroupList}>刷新</span>
                                            或稍后再试
                                        </div> :
                                        // (systemMessageContent.group_id === 0 ? [...groupsInfo, systemMessageContent] : [...groupsInfo])
                                        sortGroupList([...groupsInfo, systemMessageContent]).map(info => {
                                            return <GroupListItem 
                                                className={room_item} 
                                                key={info.group_id} 
                                                info={info} 
                                                clearCheck={() => info.no_check = 0} 
                                            />
                                        })
                            }
                        </div>
                        <div className={group_list_setting}>
                            <Dropdown 
                                overlay={(
                                    <Menu 
                                        className={group_list_setting_content}
                                        items={[
                                            {
                                                key: 'group_found',
                                                label: '寻找群组',
                                                onClick: showSearchGroup
                                            }, {
                                                key: 'group_create',
                                                label: '创建群组',
                                                onClick: showCreateGroup
                                            },
                                        ]}
                                    >
                                        {/* <Menu.Item key="group_found" onClick={showSearchGroup}>
                                            <span>寻找群组</span>
                                        </Menu.Item>
                                        <Menu.Item key="group_create" onClick={showCreateGroup}>
                                            <span>创建群组</span>
                                        </Menu.Item> */}
                                    </Menu>
                                )} 
                                trigger={['click']}
                                placement="top"
                            >
                                <MenuOutlined className={group_list_menu} />
                            </Dropdown>
                        </div>
                    </Sider>
                </Layout>
            </Layout>
            <Modal
                visible={modalVisible}
                footer={null}
                maskClosable={false}
                width={820}
                zIndex={999}
                className="group_modal"
                bodyStyle={{paddingTop: '64px', background: 'linear-gradient(to bottom, #000 0%, #fff 100%)'}}
                style={{top: '80px', minWidth: '820px', color: '#fff'}}
                onCancel={closeAllModal}
                destroyOnClose
            >
                {
                    searchGroupModalVisible ? <GroupSearch /> : 
                    createGroupModalVisible ? <GroupCreate closeModal={closeAllModal} /> : ''
                }
                
            </Modal>
        </>
    )
}


function mapStateToProps(state) {
    return {
        user: state.user,
        currentRoom: state.currentRoom
    }
}
export default connect(
    mapStateToProps,
    {
        changeCurrentRoom,
        changeCurrentRoomInfo
    }
)(GroupList);




